/*
This software is distributed under the Simplified BSD License:

Copyright (c) 2008, Chris Venter <chris.venter@gmail.com>
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, 
are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright notice, 
    	this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice, 
    	this list of conditions and the following disclaimer in the documentation 
    	and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 
DAMAGE.
*/
#ifndef GENERIK_MEDIA_H
#define GENERIK_MEDIA_H

/** \file media.h
This file contains abstract media interfaces.
*/

#include <string>
#include <list>

namespace generik
{

	/** This namespace holds media interfaces.
	*/
	namespace media
	{
	
		typedef unsigned long long uint64;

		/// the abstract player interface
		/** this defines the abstract interface to a media player.
		The player is able to open a specific uri, and perform the usual
		media operations on it. 
		*/
		struct player
		{
			virtual ~player() {}

			/// playback functions
			//@{
				/// opens the specified uri
				virtual void open(const std::string& uri_in) = 0;
				/// starts playback
				virtual void play() = 0;
				/// pauses playback
				virtual void pause() = 0;
				/// stops playback
				virtual void stop() = 0;
				/// skips forward in the current track
				virtual void fwd() = 0;
				/// skips backward in the current track
				virtual void rew() = 0;
				/// seeks a specified number of seconds relative to the current position
				virtual void seekrel(int seconds) = 0;
				/// seeks to the specified offset in seconds from the start of the track
				virtual void seek(int seconds) = 0;
			//@}

			/// query functions
			//@{
				/// returns the length of the track in microseconds(?)
				virtual uint64 len() = 0;
				/// returns the current position in the track in microseconds(?)
				virtual uint64 pos() = 0;

				/// different states the player may be in
				enum state
				{
					GMP_STOP,
					GMP_PAUSE,
					GMP_PLAY,
					GMP_ERROR
				};
				/// returns the status of the player
				/** The value of this is implementation specific, but could be one of
				"play" - playback is in progress
				"stop" - the player is not playing
				"pause" - the player is paused during playback
				"error X" - an error X has occurred - the player is usually reset to the stopped state
				in this case
				*/
				virtual state status() = 0;
				/// returns a string of the status of the player
				/** Mainly used in printf-style debugging
				*/
				static std::string printstatus(state s_in)
				{
					switch (s_in)
					{
						case GMP_STOP: 	return "STOP";
						case GMP_PAUSE:	return "PAUSE";
						case GMP_PLAY:	return "PLAY";
						case GMP_ERROR:	return "ERROR";
					}
				}
				/// returns an extended explanation of the current status
				/** This may be queried when status() returns ERROR, to find out what exactly went
				wrong during playback
				*/
				virtual std::string statusmsg() = 0;
			//@}

			/// checks the state of the player and performs default operations
			/** Any operation which should be periodically performed by the system on the player
			should be implemented in this function.
			This is a good place to put bus-message handling from the player engine, which could
			periodically be checked by a threaded loop.
			A derived player could check for end-of-stream, for example, and query its playlist
			for the next song, etc.
			*/
			virtual void _update() = 0;
			//virtual void on_error() = 0;
			virtual void on_endofstream() = 0;
		};

	}
	
}

#endif

